home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
simula
/
books
/
books.lha
/
kirkerud
/
dfweather.sim
< prev
next >
Wrap
Text File
|
1993-08-16
|
11KB
|
322 lines
% ****************************************************************
% * *
% * This is the program constructed in section 12.9 of *
% * Object Oriented Programming with Simula by Bj|rn Kirkerud; *
% * *
% ****************************************************************
begin
class Place_day(year, month, day, place_number);
integer year, month, day, place_number;
begin
! Declarations of data attributes: ;
real rain, min_temp, max_temp;
Boolean sunny;
! A variable that says whether or not data has been entered
! for this Place_day: ;
Boolean no_data;
! Declarations of procedures for accessing the data of this Place_day: ;
procedure Enter_data;
begin
rain := prompt_for_real("Rain (in mm)> ");
min_temp := prompt_for_real("Min temp.> ");
max_temp := prompt_for_real("Max temp.> ");
sunny := prompt_for_bool("Sunny? ");
no_data := false;
end;
procedure Display_data;
if not no_data then
begin
outtext("Meth. data for " & date_name(year, month, day) &
" at place " & int_as_text(place_number) & ": "); outimage;
outtext(" Rain: "); outfix(rain, 1, 0); outimage;
outtext(" Min temp: "); outfix(min_temp, 1, 0); outimage;
outtext(" Max temp: "); outfix(max_temp, 1, 0); outimage;
outtext(" It was " & (if sunny then notext else "not ") &
"sunny."); outimage;
end;
procedure Change_data;
if not no_data then
begin
! Let the user change the values of some data attributes ;
User_message("Change data is not implemented.");
end;
procedure Write_to_file(weather_file); ref(directfile) weather_file;
if not no_data then
begin
weather_file.outfix(rain, 1, 10);
weather_file.outfix(min_temp, 1, 10);
weather_file.outfix(max_temp, 1, 10);
weather_file.outint(if sunny then 1 else 0, 2);
weather_file.locate(location_number(year, month, day, place_number));
weather_file.outimage;
end of Write_to_file;
procedure Read_from_file(weather_file); ref(directfile) weather_file;
begin
weather_file.locate(location_number( year, month, day, place_number));
weather_file.inimage;
if image_is_empty(weather_file)
then no_data := true
else begin
rain := weather_file.inreal;
min_temp := weather_file.inreal;
max_temp := weather_file.inreal;
sunny := weather_file.inint = 1;
no_data := false;
end;
end of Read_from_file;
! Initialization: ;
no_data := true;
end of Place_day;
! A variable to keep a reference to the direct file where
! data about all Place_days are kept: ;
ref(directfile) weather_file;
! A procedure that calculates where in the direct file to
! put data about a Place_day: ;
integer procedure location_number( year, month, day, place_number);
integer year, month, day, place_number;
location_number := (place_number - 1)*100*366
+ year*366
+ month_start(month)
+ day;
! Procedures to handle the actions the program is able to execute: ;
procedure Enter_place_day;
begin
integer year, month, day, place_number;
ref(Place_day) a_place_day;
prompt_for_date(year, month, day);
place_number := prompt_for_int("Place-number? ");
weather_file.locate( location_number(year, month, day, place_number));
weather_file.inimage;
if not image_is_empty(weather_file)
then User_message("You have entered data for this place-day "
"previously!")
else begin
a_place_day :- new Place_day(year, month, day, place_number);
a_place_day.Enter_data;
a_place_day.Write_to_file(weather_file);
end;
end of Enter_place_day;
procedure Display_place_day;
begin
integer year, month, day, place_number;
ref(Place_day) a_place_day;
prompt_for_date(year, month, day);
place_number := prompt_for_int("Number of place? ");
a_place_day :- new Place_day(year, month, day, place_number);
a_place_day.Read_from_file(weather_file);
if a_place_day.no_data
then User_message( "No data known for this place-day!")
else a_place_day.Display_data;
end of Display_place_day;
procedure Change_place_day;
begin
integer year, month, day, place_number;
ref(Place_day) a_place_day;
prompt_for_date(year, month, day);
place_number := prompt_for_int("Number of place? ");
a_place_day :- new Place_day(year, month, day, place_number);
a_place_day.Read_from_file(weather_file);
if a_place_day.no_data
then User_message( "No data known for this place-day!")
else begin
a_place_day.Display_data;
a_place_day.Change_data;
a_place_day.Write_to_file(weather_file);
end;
end of Change_place_day;
procedure Statistics;
begin
User_message("Statistics is not implemented");
end of Statistics;
procedure Give_help;
begin
User_message("The legal commands are: ");
User_message(" ?: Help (writes this text)");
User_message(" E: To enter data about a single place-day");
User_message(" D: Writes data about a single place-day");
User_message(" C: To change data about a single place-day");
User_message(" S: Produces some statistics");
User_message(" Q: Quit (the program execution stops)");
end of Give_help;
procedure Read_and_execute_commands;
begin character command;
command := prompt_for_char("Type your first command (? for help) > ");
while command ne 'Q' do
begin
if command = '?' then Give_help else
if command = 'E' then Enter_place_day else
if command = 'D' then Display_place_day else
if command = 'C' then Change_place_day else
if command = 'S' then Statistics
else begin
outtext("Unknown command: "); outchar(command); outimage;
end;
command := prompt_for_char("Your next command > ");
end;
end of Read_and_execute_commands;
! Declarations of some auxiliary procedures: ;
text procedure int_as_text(int); integer int;
begin text t; integer a;
a := abs(int);
t :- blanks((if int < 0 then 1 else 0) +
(if a < 10 then 1 else
if a < 100 then 2 else
if a < 1000 then 3 else
if a < 10000 then 4 else
if a < 100000 then 5 else
if a < 1000000 then 6 else
if a < 10000000 then 7 else
if a < 100000000 then 8 else
if a < 1000000000 then 9 else 10));
t.putint(int);
int_as_text :- t;
end;
procedure User_message(message); text message;
begin outtext(message); outimage end;
integer procedure prompt_for_int(prompt); text prompt;
begin
outtext(prompt); breakoutimage; inimage;
prompt_for_int := inint;
end;
character procedure prompt_for_char(prompt); text prompt;
begin
outtext(prompt); breakoutimage; inimage;
prompt_for_char := inchar;
end;
real procedure prompt_for_real(prompt); text prompt;
begin
outtext(prompt); breakoutimage; inimage;
prompt_for_real := inreal;
end;
Boolean procedure prompt_for_bool(prompt); text prompt;
begin character c;
outtext(prompt); breakoutimage; inimage;
c := inchar;
prompt_for_bool := c = 'y' or c = 'Y';
end;
procedure prompt_for_date(year, month, day);
name year, month, day; integer year, month, day;
begin
year := prompt_for_int("Year? ");
month := prompt_for_int("Month? ");
day := prompt_for_int("Day? ");
if not legal_date(year, month, day) then
begin
User_message("Illegal date! Try again!");
prompt_for_date(year, month, day);
end;
end;
Boolean procedure legal_date(year, month, day);
integer year, month, day;
legal_date := 1 <= month and month <= 12 and then
1 <= day and day <= 31 and then
not (day = 31 and
(month = 4 or month = 6 or month = 9 or month = 11)) and then
not (month = 2 and day > 29) and then
not (month = 2 and day = 29 and rem(year, 4) > 0);
text procedure date_name(year, month, day); integer year, month, day;
if not legal_date(year, month, day)
then date_name :- notext
else begin text t;
t :- blanks(11);
t.sub(1, 2).putint(day);
t.sub(3, 1).putchar('.');
t.sub(4, 3) := month_name(month);
t.sub(8, 4).putint(year);
date_name :- t;
end;
text array month_name(1 : 12);
integer array month_start(1 : 12);
procedure Initialize_months;
begin
month_name( 1) :- "jan"; month_start( 1) := 1;
month_name( 2) :- "feb"; month_start( 2) := 31 + month_start( 1);
month_name( 3) :- "mar"; month_start( 3) := 29 + month_start( 2);
month_name( 4) :- "apr"; month_start( 4) := 31 + month_start( 3);
month_name( 5) :- "may"; month_start( 5) := 30 + month_start( 4);
month_name( 6) :- "jun"; month_start( 6) := 31 + month_start( 5);
month_name( 7) :- "jul"; month_start( 7) := 30 + month_start( 6);
month_name( 8) :- "aug"; month_start( 8) := 31 + month_start( 7);
month_name( 9) :- "sep"; month_start( 9) := 31 + month_start( 8);
month_name(10) :- "oct"; month_start(10) := 30 + month_start( 9);
month_name(11) :- "nov"; month_start(11) := 31 + month_start(10);
month_name(12) :- "dec"; month_start(11) := 30 + month_start(11);
end Initialize_months;
Boolean procedure image_is_empty(df); ref(directfile) df;
image_is_empty := df.image.sub(1,1).getchar = '!0!' or else
df.image.sub(1,1).getchar = '!31!' or else
df.image.sub(1,1).getchar = '!25!';
! That was the end of the declarations. Now come the imperatives: ;
! First, initialize the file: ;
weather_file :- new directfile("Weather.dta");
weather_file.setaccess("anycreate");
if not weather_file.open(blanks(10 + 10 + 10 + 2))
then User_message("File problems!")
else begin
! Then, initialize month names and month lengths: ;
Initialize_months;
! Then, read and execute commands typed by the user: ;
Read_and_execute_commands;
! Finally, close the file: ;
weather_file.close;
end;
end